from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger, InvalidPage
from django.db.models.query import QuerySet

def inc_paginate(objects, get_page, unit_page=3):
    paginator = Paginator(objects, unit_page)
    objects = None
    try:
        page = paginator.page(get_page)
        objects = page.object_list
    except PageNotAnInteger:
        page = paginator.page(1)
        objects = page.object_list
    except EmptyPage:
        objects = None
    return objects


class URLArgument(object):
    def __init__(self, arguments):
        self.arguments = arguments

    def urlencode(self):
        arguments = self.arguments.copy()
        for k,v in arguments.iteritems():
            if not v:
                arguments.pop(k)
        return arguments.urlencode()

    def encode_without(self, key):
        arguments = self.arguments.copy()
        if key in arguments:
            arguments.pop(key)
        return arguments.urlencode()

    def encode_without_page(self):
        return self.encode_without('page')

    def encode_without_order(self):
        return self.encode_without('order')


def get_objects_page_context(objects, arguments, search_form=None):
    if 'order' in arguments:
        objects = objects.order_by(arguments['order'])
    if search_form:
        objects = search_form.search(objects)
    number_of_records = 0
    if objects:
        if isinstance(objects, QuerySet):
            number_of_records = objects.count()
        else:
            number_of_records = len(objects)

    paginator = Paginator(objects, 2)
    try:
        page_num = int(arguments.get('page', '1'))
    except ValueError:
        page_num = 1
    try:
        objects_page = paginator.page(page_num)
    except (EmptyPage, InvalidPage):
        objects_page = paginator.page(paginator.num_pages)

    adjacent_pages = 2
    page_numbers = [n for n in \
                    range(page_num - adjacent_pages, page_num + adjacent_pages + 1) \
                    if n > 0 and n <= paginator.num_pages]
    return {
        'page_num': page_num,
        'objects_page': objects_page,
        'number_of_records': number_of_records,
        'url_arguments': URLArgument(arguments),
        'search_form': search_form,

        'page_numbers': page_numbers,
        'next': objects_page.next_page_number(),
        'previous': objects_page.previous_page_number(),
        'has_next': objects_page.has_next(),
        'has_previous': objects_page.has_previous,
        'show_first': 1 not in page_numbers,
        'show_last': paginator.num_pages not in page_numbers,
        'last_page': paginator.num_pages,
        }